﻿#include "DeviceDBManager.h"
#include "global.h"

DeviceDBManager* DeviceDBManager::instance = nullptr;
DeviceDBManager::DeviceDBManager(): mydb("LinuxPad.db"),
    mSubConfigDB(mydb,"SubConfig"),
    mPortConfigDB(mydb,"PortConfig"),
    mDeviceConfigDB(mydb,"DeviceConfig"),
    mGoodsInfoDB(mydb,"GoodsInfo"),
    mUserInfoDB(mydb,"UserInfo")
{
    //节 层 面 长度 规格 数量 定位位置
    QString fields = "id INTEGER PRIMARY KEY,sub INTEGER,layer INTEGER,face TEXT,lenth INTEGER, standard INTEGER, count INTEGER,positionX INTEGER,positionY INTEGER";
    if(mSubConfigDB.createTable(fields))
        mylog<< "SubConfig Table created successfully";
    else
        mylog<< "SubConfig Table created failed";

    //规格 数量
    fields = "id INTEGER PRIMARY KEY,standard INTEGER, position INTEGER";
    if(mPortConfigDB.createTable(fields))
        mylog<< "PortConfig Table created successfully";
    else
        mylog<< "PortConfig Table created failed";

    //设置字段 值string
    fields = "type TEXT PRIMARY KEY,value TEXT";
    if(mDeviceConfigDB.createTable(fields))
        mylog<< "DeviceConfig Table created successfully";
    else
        mylog<< "DeviceConfig Table created failed";

    //id 层 格 面 规格 状态 X Y 代价距离
    fields = "id INTEGER PRIMARY KEY,layer INTEGER, cell INTEGER,face TEXT, standard INTEGER, state INTEGER,positionX INTEGER,positionY INTEGER,cost INTEGER";
    if(mGoodsInfoDB.createTable(fields))
        mylog<< "GoodsInfo Table created successfully";
    else
        mylog<< "GoodsInfo Table created failed";

    //id 用户名 密码 脸id 指纹id 角色
    fields = "name TEXT PRIMARY KEY, pwd TEXT,faceid INTEGER, fingerid INTEGER, role INTEGER,createtime TEXT,altertime TEXT,state INTEGER";
    if(mUserInfoDB.createTable(fields))
        mylog<< "UserInfoDB Table created successfully";
    else
        mylog<< "UserInfoDB Table created failed";
}

void DeviceDBManager::initDeviceInfo()
{
    if(!containsDeviceInfo("TotalSub"))
        mDeviceConfigDB.insertRecord(QVariantList{"TotalSub","1"});
    if(!containsDeviceInfo("TotalLayer"))
        mDeviceConfigDB.insertRecord(QVariantList{"TotalLayer","4"});
    if(!containsDeviceInfo("PortLayer"))
        mDeviceConfigDB.insertRecord(QVariantList{"PortLayer","3"});
    if(!containsDeviceInfo("ServerUrl"))
        mDeviceConfigDB.insertRecord(QVariantList{"ServerUrl","192.168.0.99:8080"});
    if(!containsDeviceInfo("DeviceNo"))
        mDeviceConfigDB.insertRecord(QVariantList{"DeviceNo","1"});
    if(!containsDeviceInfo("DeviceIP"))
        mDeviceConfigDB.insertRecord(QVariantList{"DeviceIP","192.168.0.99"});
    if(!containsDeviceInfo("DevicePort"))
        mDeviceConfigDB.insertRecord(QVariantList{"DevicePort","22222"});
    if(!containsDeviceInfo("DeviceGate"))
        mDeviceConfigDB.insertRecord(QVariantList{"DeviceGate","192.168.0.1"});
    if(!containsDeviceInfo("DeviceName"))
        mDeviceConfigDB.insertRecord(QVariantList{"DeviceName","人事柜"});
    if(!containsDeviceInfo("MainTitle"))
        mDeviceConfigDB.insertRecord(QVariantList{"MainTitle","无人仓智能档案柜控制系统"});
    if(!containsDeviceInfo("LastLoginUser"))
        mDeviceConfigDB.insertRecord(QVariantList{"LastLoginUser","admin"});
    if(!containsDeviceInfo("RemenberPwd"))                                  //因为value存储类型是TEXT，所以用数字来保存bool值，读取时直接转int即可
        mDeviceConfigDB.insertRecord(QVariantList{"RemenberPwd","1"});
    if(!containsDeviceInfo("SystemDesployTime"))                            //软件第一次运行时间，用于生成授权的序列号和判断是否到达授权期限
        mDeviceConfigDB.insertRecord(QVariantList{"SystemDesployTime",QDateTime::currentDateTime().toString("yyyyMMddhhmmss")});
    if(!containsDeviceInfo("GrantNo"))                                      //是否已授权，0和非0
        mDeviceConfigDB.insertRecord(QVariantList{"GrantNo","0"});
    if(!containsDeviceInfo("PostponeTime"))                                 //延期试用次数
        mDeviceConfigDB.insertRecord(QVariantList{"PostponeTime","0"});

    if(!containsUserName("admin"))
        mUserInfoDB.insertRecord(QVariantList{"admin","123456",-1,-1,-1,QDateTime::currentDateTime().toString(Qt::ISODate),QDateTime::currentDateTime().toString(Qt::ISODate),UserState::normal});
}

bool DeviceDBManager::containsDeviceInfo(QString type)
{
    QVariantMap filed;
    filed.insert("type",type);
    return mDeviceConfigDB.containRecord(filed);
}

bool DeviceDBManager::containsUserName(QString name)
{
    QVariantMap filed;
    filed.insert("name",name);
    return mUserInfoDB.containRecord(filed);
}
/***************************************************************
* 函数名称：getDeviceInfo(QString type)
* 功能描述：获取指定字段的信息
* 参数说明：type-设备具体信息
* 返回值说明：value
***************************************************************/
QVariant DeviceDBManager::getDeviceInfo(QString type)
{
    QVariantMap condition;
    QList<QVariantList> value;
    condition.insert("type",type);
    bool ok = mDeviceConfigDB.searchRecords(condition,value);
    if(ok)
    {
        return value[0][1];
    }
    return -1;
}

bool DeviceDBManager::setDeviceInfo(QString type, QString value)
{
    QVariantMap condition{{"type",type}};
    QVariantMap values{{"value",value}};
    bool result = mDeviceConfigDB.updateRecord(condition,values);
    return result;
}
/***************************************************************
* 函数名称：getSubInfo(SubInfoModel &subinfo)
* 功能描述：获取指定的第几节第几层的具体信息
* 参数说明：subinfo-layer和sub必须已经指定
* 返回值说明：查询是否成功
***************************************************************/
bool DeviceDBManager::getSubInfo(SubInfoModel &subinfo)
{
    QVariantMap condition;
    QList<QVariantList> value;
    condition.insert("sub",subinfo.sub);
    condition.insert("layer",subinfo.layer);
    condition.insert("face",subinfo.face);

    bool ok = mSubConfigDB.searchRecords(condition,value);
    if(ok)
    {
        subinfo.length = value[0][4].toInt();
        subinfo.standard = value[0][5].toInt();
        subinfo.count = value[0][6].toInt();
        subinfo.positionX = value[0][7].toInt();
        subinfo.positionY = value[0][8].toInt();
    }
    return ok;
}

bool DeviceDBManager::getGoodsPosition(InOutCabCommand_Server cmdserver, InOutCabCommand_Board &cmdboard)
{
    QVariantMap condition;
    QList<QVariantList> value;
    //先查出货口位置
    condition.insert("id",cmdserver.PortNo);
    condition.insert("standard",cmdserver.Standard);
    mPortConfigDB.searchRecords(condition,value);
    if(value.empty())
    {
        return false;
    }
    cmdboard.PortLocation_X = value[0][2].toInt();

    //再查货位位置
    condition.clear();
    value.clear();
    condition.insert("layer",cmdserver.LayerNo);
    condition.insert("cell",cmdserver.CellNo);
    condition.insert("face",cmdserver.Face);
    mGoodsInfoDB.searchRecords(condition,value);
    if(value.empty())
    {
        return false;
    }
    cmdboard.StorgeLocation_X = value[0][6].toInt();
    cmdboard.StorgeLocation_Y = value[0][7].toInt();
    return true;
}

bool DeviceDBManager::getUserRole(QString name, int &role)
{
    QVariantMap condition;
    QList<QVariantList> value;
    //先查出货口位置
    condition.insert("name",name);
    bool result = mUserInfoDB.searchRecords(condition,value);
    if(!result || value.empty())
    {
        return false;
    }
    role = value[0][4].toInt();
    return result;
}

bool DeviceDBManager::getUserPwd(QString name, QString &pwd)
{
    QVariantMap condition;
    QList<QVariantList> value;
    //先查出货口位置
    condition.insert("name",name);
    bool result = mUserInfoDB.searchRecords(condition,value);
    if(!result || value.empty())
    {
        return false;
    }
    pwd = value[0][1].toString();
    return result;
}

bool DeviceDBManager::setGoodsState(InOutCabCommand_Server cmd, StorgeGoodsState state)
{
    //搜索条件--货位
    QVariantMap conditions{{"layer",cmd.LayerNo},{"cell",cmd.CellNo},{"face",cmd.Face}};
    //根据出入柜更新货位状态为占据还是空闲
    QVariantMap values;
    values.insert("state",state);
    mGoodsInfoDB.updateRecord(conditions,values);
    return true;
}

bool DeviceDBManager::getGoodsState(InOutCabCommand_Server cmd, StorgeGoodsState &state)
{
    //搜索条件--货位
    QVariantMap conditions{{"layer",cmd.LayerNo},{"cell",cmd.CellNo},{"face",cmd.Face}};
    QList<QVariantList> record;
    bool result = mGoodsInfoDB.searchRecords(conditions,record);
    if(!result)
        return result;
    state = (StorgeGoodsState)record[0][5].toInt();
    return result;
}

bool DeviceDBManager::distributeGoods(InOutCabCommand_Server &cmd)
{
    QVariantMap conditions{{"standard",cmd.Standard},{"state",StorgeGoodsState::State_Free}};
    QVariantList record;
    bool result = mGoodsInfoDB.getMinRecord(conditions,"cost",record);
    if(result && !record.empty())
    {
        cmd.LayerNo = record[1].toInt();
        cmd.CellNo = record[2].toInt();
        cmd.Face = record[3].toString();
        //将该货位设置成占据状态，避免该指令还未执行之前，再把相同的位置分配给其他指令
        mGoodsInfoDB.updateRecord(QVariantMap{{"id",record[0].toInt()}},QVariantMap{{"state",StorgeGoodsState::State_Occupy}});
    }
    return result;
}





